home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / rlogin.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  11KB  |  501 lines

  1. /****************************************************************************
  2. *    $Id: rlogin.c 1.8 93/07/16 11:49:47 ROOT_DOS Exp $
  3. *    24 Oct 92    1.1        GT    Add ZMODEM.                                        *
  4. *    17 Jan 93    1.2        GT    Don't delete first 4 characters from remote.    *
  5. *                            Fix XMODEM download prompt.                        *
  6. *    30 Jan 93    1.3        GT    Fix background file transfers.                    *
  7. *    07 Feb 93    1.4        GT    Re-enable ZMODEM upload.                        *
  8. *    20 Feb 93    1.5        GT    Debugging Tx again.                                *
  9. *    21 Feb 93    1.6        GT    And again.                                        *
  10. *    22 Feb 93    1.7        GT    Only allow one file transfer at a time.            *
  11. *    08 May 93    1.8        GT    Fix warnings.                                    *
  12. *
  13. *  ATARI Version by David Nash - dnash@chaos.demon.co.uk
  14. *
  15. *  __stdargs rlo_output, dorsh, dorlogin
  16. *
  17. ****************************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include    <ctype.h>
  21. #include "global.h"
  22. #include "mbuf.h"
  23. #include "socket.h"
  24. #include "session.h"
  25. #include "proc.h"
  26. #include "tty.h"
  27. #include "commands.h"
  28. #include "netuser.h"
  29. #include    "sz.h"
  30.  
  31. #if    0
  32. static char *username = "guest";
  33. #endif
  34. static char terminal[] = "vt102";
  35. static char *termspeed = "/38400";
  36. static char logname[16];
  37.  
  38. extern FILE *Rawterm;
  39. int rlo_connect __ARGS ((struct session * sp, char *fsocket, int len));
  40. void __stdargs rlo_output __ARGS ((int unused, void *p1, void *p2));
  41. void rlrecv __ARGS ((struct session * sp));
  42. static int dorwhatever __ARGS ((int argc, char *argv[], void *p));
  43. static void file_xfer __ARGS ((int s, int direction, struct session * sp));
  44. #if    0
  45. static void reporter __ARGS ((int type, void *data));
  46. #endif
  47.  
  48. #if    0
  49. static char recv_ok;         /* nz - ok to run receive                 */
  50. #endif
  51.  
  52. /* Execute user rsh command */
  53. int __stdargs dorsh (argc, argv, p)
  54. int argc;
  55. char *argv[];
  56. void *p;
  57.  
  58.     {
  59.     return 0;
  60.     }
  61.  
  62. /* Execute user rlogin command */
  63. int __stdargs dorlogin (argc, argv, p)
  64. int argc;
  65. char *argv[];
  66. void *p;
  67.  
  68.     {
  69.     return dorwhatever (argc, argv, p);
  70.     }
  71.  
  72. /* Execute some sort of r command */
  73. static int dorwhatever (argc, argv, p)
  74. int argc;
  75. char *argv[];
  76. void *p;
  77.  
  78.     {
  79.     struct session *sp;
  80.     struct sockaddr_in fsocket;
  81.     struct sockaddr_in lsocket;
  82.  
  83.     /* Make sure this comes from console - WG7J */
  84.  
  85.     if (Curproc->input != Command->input)
  86.         return 0;
  87.  
  88.     /* Allocate a session descriptor */
  89.  
  90.     if ((sp = newsession (argv[1], RLOGIN)) == NULLSESSION)
  91.         {
  92.         tputs ("Too many sessions");
  93.         return 1;
  94.         }
  95.  
  96.     fsocket.sin_family = AF_INET;
  97.     if (argc < 3)
  98.         fsocket.sin_port = IPPORT_RLOGIN;
  99.     else
  100.         fsocket.sin_port = atoi (argv[2]);
  101.  
  102.     tprintf ("Resolving %s... ", sp->name);
  103.     if ((fsocket.sin_addr.s_addr = resolve (sp->name)) == 0L)
  104.         {
  105.         tprintf (Badhost, sp->name);
  106.         keywait (NULLCHAR, 1);
  107.         freesession (sp);
  108.         return 1;
  109.         }
  110.  
  111.     if ((sp->s = socket (AF_INET, SOCK_STREAM, 0)) == -1)
  112.         {
  113.         tputs ("No Socket");
  114.         keywait (NULLCHAR, 1);
  115.         freesession (sp);
  116.         return 1;
  117.         }
  118.  
  119.     lsocket.sin_family = AF_INET;
  120.     lsocket.sin_addr.s_addr = INADDR_ANY;
  121.     lsocket.sin_port = IPPORT_RLOGIN;
  122.     bind (sp->s, (char *) &lsocket, sizeof (lsocket));
  123.     return rlo_connect (sp, (char *) &fsocket, SOCKSIZE);
  124.     }
  125.  
  126. /* Generic interactive connect routine */
  127.  
  128. int rlo_connect (sp, fsocket, len)
  129. struct session *sp;
  130. char *fsocket;
  131. int len;
  132.     {
  133.     unsigned int index;
  134.  
  135.     index = (unsigned int) (sp - Sessions);
  136.  
  137.     sockmode (sp->s, SOCK_ASCII);
  138.     tprintf ("Trying %s...\n", psocket ((struct sockaddr *) fsocket));
  139.     if (connect (sp->s, fsocket, len) == -1)
  140.         {
  141.         tprintf ("%s session %u failed: %s errno %d\n",
  142.                  Sestypes[sp->type], index, sockerr (sp->s), errno);
  143.         keywait (NULLCHAR, 1);
  144.         freesession (sp);
  145.         return 1;
  146.         }
  147.  
  148.     tprintf ("%s session ", Sestypes[sp->type]);
  149.     tprintf ("%u connected to %s\n", index, sp->name);
  150.     rlrecv (sp);
  151.     return 0;
  152.     }
  153.  
  154. /* Rlogin input routine, common to both rlogin and ttylink */
  155.  
  156. void rlrecv (sp)
  157. struct session *sp;
  158.     {
  159.     int c, s, index;
  160.     char *cp;
  161.  
  162.     s = sp->s;
  163.  
  164.     /* Get the login name. */
  165.  
  166.     tprintf ("login: ");
  167.     recvline (sp->input, logname, sizeof (logname));
  168.     *(logname + strlen (logname) - 1) = '\0';     /* delete \n                 */
  169.  
  170.     /* We run both the network and local sockets in transparent mode
  171.      * because we have to do our own eol mapping */
  172.  
  173.     seteol (s, "");
  174.     seteol (Curproc->input, "");
  175.     seteol (Curproc->output, "");
  176.  
  177.     /* Read real keystrokes from the keyboard */
  178.  
  179.     sp->ttystate.crnl = 0;
  180.  
  181.     /* Put tty into raw mode */
  182.  
  183.     sp->ttystate.echo = 0;
  184.     sp->ttystate.edit = 0;
  185.  
  186.     setflush (s, '\n');
  187.  
  188.     index = (int) (sp - Sessions);
  189.  
  190.     /* Fork off the transmit process */
  191.  
  192. #if    0
  193.     recv_ok = 1;
  194. #endif
  195.     sp->proc1 = newproc ("rlo_out", 2048, rlo_output, 0, sp, NULL, 0);
  196.  
  197. #if    0
  198.     for (c = 0; c < 4; c++)
  199.         (void) recvchar (s);                     /* get response                     */
  200. #endif
  201.  
  202.     /* Process input on the connection */
  203.  
  204.     while ((c = recvchar (s)) != -1)
  205.         {
  206.         if (c == '\r' || c == '\n')
  207.             {
  208.             seteol (Curproc->output, "\r\n");
  209.             tputc ((char) c);
  210.             seteol (Curproc->output, "");
  211.             }
  212.         else
  213.             {
  214.             tputc ((char) c);
  215.             }
  216.  
  217.         }
  218.  
  219. #if    0
  220.     for (;;)
  221.         {
  222.         if (recv_ok == 0)
  223.             pwait (&recv_ok);            /* suspended                        */
  224.  
  225.         if (socklen (s, 0) == 0)
  226.             {
  227.             pwait (NULL);                /* nothing to do                    */
  228.             continue;
  229.             }
  230.  
  231.         if ((c = recvchar (s)) == -1)
  232.             break;                        /* socket failed                    */
  233.  
  234.         if (c == '\r' || c == '\n')
  235.             {
  236.             seteol (Curproc->output, "\r\n");
  237.             tputc ((char) c);
  238.             seteol (Curproc->output, "");
  239.             }
  240.         else
  241.             {
  242.             tputc ((char) c);
  243.             }
  244.  
  245.         }    /* for (;;) */
  246. #endif    
  247.  
  248. quit:                                             /* A close was received from
  249.                                                   * the remote host. Notify
  250.                                                   * the user, kill the output
  251.                                                   * task and wait for a
  252.                                                   * response from the user
  253.                                                   * before freeing the
  254.                                                   * session. */
  255.  
  256.     cp = sockerr (s);
  257.     seteol (s, "\r\n");
  258.     seteol (Curproc->input, "\r\n");
  259.     seteol (Curproc->output, "\r\n");
  260.  
  261.     tprintf ("%s session %u", Sestypes[sp->type], index);
  262.     tprintf (" closed: %s\n", cp != NULLCHAR ? cp : "EOF");
  263.     killproc (sp->proc1);
  264.     sp->proc1 = NULLPROC;
  265.     close_s (sp->s);
  266.     sp->s = -1;
  267.     keywait (NULLCHAR, 1);
  268.     freesession (sp);
  269.     }
  270.  
  271.     
  272. /* User rlogin output task, started by user rlogin command */
  273. void __stdargs rlo_output (unused, sp1, p)
  274. int unused;
  275. void *sp1;
  276. void *p;
  277.     {
  278.     struct session *sp;
  279.     struct mbuf *bp;
  280.     char *cp;
  281.     int c;
  282.  
  283.     sp = (struct session *) sp1;
  284.  
  285. #if    0
  286.     logname = getenv ("USER");
  287.     if (logname == NULLCHAR)
  288.         logname = username;
  289. #endif
  290.     bp = ambufw (1 + strlen (logname) + 1 + strlen (logname) + 1 +
  291.                  strlen (terminal) + strlen (termspeed) + 1);
  292.  
  293.     cp = bp->data;
  294.     *cp++ = '\0';
  295.     strcpy (cp, logname);
  296.     cp += strlen (logname) + 1;
  297.     strcpy (cp, logname);
  298.     cp += strlen (logname) + 1;
  299.     strcpy (cp, terminal);
  300.     cp += strlen (terminal);
  301.     strcpy (cp, termspeed);
  302.     cp += strlen (termspeed) + 1;
  303.     bp->cnt = cp - bp->data;
  304.     if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) != -1)
  305.         {
  306.         /* Send whatever's typed on the terminal */
  307.  
  308. #if    0
  309.         while (recv_mbuf (sp->input, &bp, 0, NULLCHAR, 0) > 0)
  310.             {
  311.             if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) == -1)
  312.                 break;
  313.  
  314.             }
  315. #endif
  316.  
  317.         while ((c = recvchar (sp->input)) != EOF)
  318.             {
  319.             /* Check for escape. */
  320.  
  321.             if (c == '~')
  322.                 {
  323.                 c = recvchar (sp->input);
  324.                 if (c == EOF)
  325.                     break;
  326.  
  327.                 switch (c)
  328.                     {
  329.                     case 'u':
  330.                     case 'd':
  331.                         file_xfer (sp->s, c, sp);     /* do [XYZ]MODEM        */
  332.                         continue;
  333.  
  334.                     }
  335.  
  336.                 }                                 /* if (c == '~') */
  337.  
  338.             /* Send the data. */
  339.  
  340.             usputc (sp->s, (char) c);
  341.             usflush (sp->s);
  342.             }    /* while ((c = recvchar (sp->input)) != EOF) */
  343.  
  344.         }
  345.  
  346.     /* Make sure our parent doesn't try to kill us after we exit */
  347.  
  348.     sp->proc1 = NULLPROC;
  349.     }
  350.  
  351.     
  352. /****************************************************************************
  353. *    file_xfer                                                                *
  354. *    Do an [XYZ]MODEM file transfer.                                            *
  355. ****************************************************************************/
  356.  
  357. static void file_xfer (s, direction, sp)
  358. int s;
  359. int direction;
  360. struct session *sp;
  361.     {
  362.     char buf[65];                        /* input buffer                        */
  363.     int protocol;                         /* protocol (X, Y, Z)                */
  364.     char *filenames[2];                     /* list of file names                */
  365. #if    0
  366.     int oldmode;                         /* old socket mode                    */
  367.     int oldflush;                         /* old flush character                */
  368. #endif
  369.     char *rcv_opts = "bvv";                /* file transfer options            */
  370.     char *send_opts = "bvv";
  371.     static int xferring = 0;            /* nz - transfer running            */
  372.     
  373.     /* Suspend the receive process. */
  374.  
  375.     sp->ttystate.crnl = 1;
  376.     sp->ttystate.echo = 1;
  377.     sp->ttystate.edit = 1;
  378.     seteol (Curproc->input, "\r\n");
  379.     seteol (Curproc->output, "\r\n");
  380.  
  381.     /* See if we are already doing a file transfer. */
  382.  
  383.     if (xferring != 0)
  384.         {
  385.         tprintf ("Sorry - only one file transfer at a time\n");
  386.         sp->ttystate.crnl = 0;
  387.         sp->ttystate.echo = 0;
  388.         sp->ttystate.edit = 0;
  389.         seteol (Curproc->input, "");
  390.         seteol (Curproc->output, "");
  391.         return;
  392.         }
  393.  
  394.     xferring = 1;
  395.     suspend (sp->proc);
  396.  
  397.     /* Get the protocol type. */
  398.  
  399.     do
  400.         {
  401.         tprintf ("\nProtocol (XYZ): ");
  402.         recvline (sp->input, buf, sizeof (buf));
  403.         protocol = tolower (*buf);
  404.         } while (protocol != 'x' && protocol != 'y' && protocol != 'z');
  405.  
  406.     /* Get the file path if required. */
  407.  
  408.     if (protocol == 'x' || direction == 'u')
  409.         {
  410.         tprintf ("File path: ");
  411.         recvline (sp->input, buf, sizeof (buf));
  412.         *(buf + strlen (buf) - 1) = '\0';
  413.         }
  414.  
  415.     /* Do the transfer. */
  416.  
  417.     filenames[0] = buf;
  418.     filenames[1] = "";
  419.     if (direction == 'u')
  420.         (void) _sendfile (s, protocol, send_opts, filenames, NULL);
  421.     else
  422.         {
  423.         if (protocol == 'x')
  424.             (void) _getfile (s, protocol, rcv_opts, filenames[0], NULL);
  425.         else
  426.             (void) _getfile (s, protocol, rcv_opts, NULL, NULL);
  427.  
  428.         }
  429.  
  430.     /* Restart the receive process. */
  431.  
  432.     usflush (s);
  433.  
  434.     /* Reset raw mode. */
  435.  
  436.     sp->ttystate.crnl = 0;
  437.     sp->ttystate.echo = 0;
  438.     sp->ttystate.edit = 0;
  439.     seteol (Curproc->input, "");
  440.     seteol (Curproc->output, "");
  441.     xferring = 0;
  442.     resume (sp->proc);
  443.     pwait (NULL);
  444.     }
  445.  
  446. #if    0    
  447. /****************************************************************************
  448. *    reporter                                                                *
  449. *    Do report functions for ZMODEM.                                            *
  450. ****************************************************************************/
  451.  
  452. static void reporter (type, data)
  453. int type;
  454. void *data;
  455.     {
  456. #if    0
  457. #if    0
  458.     Current->ttystate.echo = 1;
  459.     Current->ttystate.crnl = 1;
  460.     Current->ttystate.edit = 1;
  461. #endif
  462.  
  463.     switch (type)
  464.         {
  465.         case 0:                                 /* filename                             */
  466.             tprintf ("FILE: %s", (char *) data);
  467.             break;
  468.  
  469.         case 1:                                 /* transfer count                     */
  470.             tprintf ("\r%7ld", *((long *) data));
  471.             break;
  472.  
  473.         case 2:                                 /* other text                         */
  474.             seteol (Curproc->output, "\r\n");
  475.             tprintf ("\n%s", (char *) data);
  476.             seteol (Curproc->output, "");
  477.             break;
  478.  
  479.         case 3:                                 /* end of transfer                     */
  480.             seteol (Curproc->output, "\r\n");
  481.             tprintf ("\n%7d files transferred.\n", *((int *) data));
  482.             seteol (Curproc->output, "");
  483.             break;
  484.  
  485.         default:
  486.             seteol (Curproc->output, "\r\n");
  487.             tprintf ("\nreporter: unknown type %d\n", type);
  488.             seteol (Curproc->output, "");
  489.             break;
  490.         }                                         /* switch (type) */
  491.  
  492.     usflush (Curproc->output);
  493. #if    0
  494.     Current->ttystate.echo = 0;
  495.     Current->ttystate.crnl = 0;
  496.     Current->ttystate.edit = 0;
  497. #endif
  498. #endif
  499.     }     /* static void reporter (int type, void *data) */
  500. #endif
  501.